##############
# (*) Kaleidoscope
# By: Allan Spale
# July 2008

from Kaleidoscope.KSTransactionFactory \
    import KSTransactionFactory, KSTransactionFactoryError
from Kaleidoscope.KSTransactionBSDDB import KSTransactionBSDDB
from Kaleidoscope.KSTransaction import KSTransactionError

from bsddb import db

class KSTransactionFactoryBSDDB(KSTransactionFactory):
    """
    Provide a general transaction factory that is not tied to a particular
    datastore platform. The interface for this object is based on BSDDB.

    """
    db_env_type = type(db.DBEnv(0))

    def __init__(self, environment):
        """
        Receive the environment used to generate the start of the transaction.

        """
        try:
            if (isinstance(environment, KSTransactionFactoryBSDDB.db_env_type)):
                super(KSTransactionFactoryBSDDB, self).__init__(environment)
            else:
                KSTransactionFactoryError.print_and_raise_error(
                    u'The environment object must be of type db.DBEnv.',
                    KSTransactionFactoryError.B_CLASS_EXCEPTION)

        except KSTransactionFactoryError:
            KSTransactionFactoryError.print_and_raise_error(
                u'An error occurred creating the transaction factory.',
                KSTransactionFactoryError.B_UNKNOWN_EXCEPTION)


    def create_transaction(self, kstx_parent_transaction, i_flags,
                               fn_caller):
        """
        Generate a new transaction that includes the function that created
        the transaction object.

        """
        try:
            if (isinstance(kstx_parent_transaction, KSTransactionBSDDB) or
                kstx_parent_transaction == None):
                if (isinstance(i_flags, int)):
                    bsddb_txn = self.environment.txn_begin(
                        kstx_parent_transaction, i_flags)
                    return KSTransactionBSDDB(bsddb_txn, fn_caller)
                else:
                    KSTransactionFactoryError.print_and_raise_error(
                        u'The environment object must be of type db.DBEnv.',
                        KSTransactionFactoryError.B_CLASS_EXCEPTION)
            else:
                KSTransactionFactoryError.print_and_raise_error(
                    u'The flags object must be of type integer.',
                    KSTransactionError.B_CLASS_EXCEPTION)
        except Exception:
            KSTransactionFactoryError.print_and_raise_error(u'A new transaction '
                + u'object could not be created becuase of an unknown error.',
                KSTransactionFactoryError.B_CLASS_EXCEPTION)